package com.validator;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

/**
 * Classe de validation d'une adresse e-mail.
 * @author Cyril Schumacher
 * @see
 * http://www.itcuties.com/j2ee/jsf-2-custom-validation-the-email-validation-example/
 */
@FacesValidator("emailValidator")
public class EmailValidator implements Validator {
    // <editor-fold defaultstate="collapsed" desc="Constantes.">
    /**
     * Modèle pour l'adresse e-mail.
     */
    private final static String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
    /**
     * Modèle compilé.
     */
    private final static Pattern EMAIL_COMPILED_PATTERN = Pattern.compile(EMAIL_PATTERN);
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Méthodes.">
    /**
     * Lève un message d'erreur.
     * @param summary Message d'erreur.
     * @param details Détails de l'erreur.
     */
    private void _CreateErrorMessage(String summary, String details) {
        FacesMessage msg = new FacesMessage(summary, details);
        msg.setSeverity(FacesMessage.SEVERITY_ERROR);
        throw new ValidatorException(msg);
    }

    /**
     * Détermine si une valeur corresponds à une adresse e-mail valide.
     * @param value Valeur.
     * @return Retourne TRUE si c'est une adresse e-mail valide, FALSe sinon.
     */
    private Boolean _IsValidEmail(String value) {
        Matcher matcher = EMAIL_COMPILED_PATTERN.matcher(value);
        return matcher.matches() == true;
    }

    /**
     * Valide la valeur.
     * @param context Informations contextuelles associées au traitement de la
     * requête.
     * @param component Composant graphique.
     * @param value Valeur.
     * @throws ValidatorException
     */
    @Override
    public void validate(FacesContext context, UIComponent component, Object value)
            throws ValidatorException {

        // Vérifie si la valeur est de type chaîne de caractère et non-vide.
        if (value instanceof String) {
            if (value.equals("") == false) {
                // Analyse la chaîne de caractère pour déterminer si c'est une
                // adresse e-mail valide.
                if (_IsValidEmail(value.toString()) == false) {
                    _CreateErrorMessage("Adresse e-mail invalide.",
                            "La valeur ne corresponds pas à une adresse e-mail.");
                }
            } else {
                _CreateErrorMessage("Aucune valeur.",
                        "Une valeur est attendue pour l'adresse e-mail.");
            }
        }
    }
    // </editor-fold>
}
